iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
自我挑戰組

非資工本科的Leetcode刷題筆記系列 第 12

Day 12 - Linked List - Two Pointer Problem 1

  • 分享至 

  • xImage
  •  

這兩題的解法就跟上一篇講的一樣,基本上就是要想辦法用雙指針演算法去解題。

141. Linked List Cycle

題目

Given head, the head of a linked list, determine if the linked list has a cycle in it.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter.

Return true if there is a cycle in the linked list. Otherwise, return false.

Example 1:

https://ithelp.ithome.com.tw/upload/images/20230927/20140728lRRmAn7GN4.png

Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).

Example 2:

https://ithelp.ithome.com.tw/upload/images/20230927/2014072863Ui9nxzrD.png

Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 0th node.

Example 3:

https://ithelp.ithome.com.tw/upload/images/20230927/201407282HKbcbkg5l.png

Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.

Constraints:

  • The number of the nodes in the list is in the range [0, 10^4].
  • 10^5 <= Node.val <= 10^5
  • pos is 1 or a valid index in the linked-list.

Follow up: Can you solve it using O(1) (i.e. constant) memory?

解法(Java)

Runtime: 0 ms
Memory Usage: 43.2 MB

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) return false;
        
        ListNode slow = head;
        ListNode fast = head;
        
        while (fast != null && fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) return true;
        }
        return false;
    }
}

142. Linked List Cycle II

題目

Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to (0-indexed). It is -1 if there is no cycle. Note that pos is not passed as a parameter.

Do not modify the linked list.

Example 1:

https://ithelp.ithome.com.tw/upload/images/20230927/20140728LZPWsMKzwn.png

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

https://ithelp.ithome.com.tw/upload/images/20230927/20140728k9PYcwr9dc.png

Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

https://ithelp.ithome.com.tw/upload/images/20230927/20140728mpce2BbIc0.png

Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

Constraints:

  • The number of the nodes in the list is in the range [0, 104].
  • 105 <= Node.val <= 105
  • pos is 1 or a valid index in the linked-list.

Follow up: Can you solve it using O(1) (i.e. constant) memory?

解法(Java)

這題寫了兩個解法,第一個一樣是用雙指針演算法去解,先使用slowfast判斷是否有循環結構,如果有循環結構的話就從slowfast相遇的節點,開始讓headfast同步往前至循環結構的交會點。

Runtime: 0 ms
Memory Usage: 43.3 MB

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) return null;

        ListNode slow = head;
        ListNode fast = head;

        while (fast.next != null && fast.next.next !=null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                while (head != fast) {
                    head = head.next;
                    fast = fast.next;
                }
                return head;
            }
        }

        return null;
    }
}

第二個解法則是我試了一下,使用Set去儲存看過的節點,如果在遇到尾端(null)前碰到看過的節點,那個節點就是循環結構的交會點。

Runtime: 2 ms
Memory Usage: 43.6 MB

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) return null;
        Set<ListNode> seen = new HashSet<>();

        ListNode temp = head;
        while (seen.add(temp)) {
            if (temp.next != null) {
                temp = temp.next;
            } else {
                return null;
            }
        }

        return temp;
    }
}

小結

這兩題就是上一篇文章帶出的題目,練習使用雙指針演算法去解題,在第二題有嘗試使用其他解法,但不管是時間還是空間上都輸雙指針演算法。


上一篇
Day 11 - Linked List - Two Pointer Technique
下一篇
Day 13 - Linked List - Two Pointer Problem 2
系列文
非資工本科的Leetcode刷題筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言